package org.bingo.controller;

import cn.dev33.satoken.annotation.SaCheckLogin;
import org.bingo.dto.AddVideoDto;
import org.bingo.dto.UpdateVideoDto;
import org.bingo.dto.VideoInfoDto;
import org.bingo.dto.VideoPageableDto;
import org.bingo.entity.Video;
import org.bingo.misc.Result;
import org.bingo.misc.ResultState;
import org.bingo.service.VideoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
@RequestMapping("/video")
public class VideoController {

    @Autowired
    private VideoService videoService;

    @PostMapping("")
    public Result video(@RequestBody VideoPageableDto videoPageableDto) {
        List<Video> videoByPage = videoService.getVideoByPage(videoPageableDto.getPage(),
                videoPageableDto.getCountPerPage());

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videoByPage.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setId(video.getId());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDtoList.add(videoInfoDto);
        });

        return Result.build(ResultState.OK, videoInfoDtoList);
    }

    @GetMapping("/alltype")
    public Result getAllSupportType() {
        List<String> typeList = new ArrayList<>();
        videoService.getAllVideoType().forEach(videoType -> typeList.add(videoType.getTypeName()));
        return Result.build(ResultState.OK, typeList);
    }

    @GetMapping("/{type}")
    public Result getVideoByType(@PathVariable("type") String type) {
        List<Video> videoByTypePage = videoService.getVideoByType(type);

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videoByTypePage.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setId(video.getId());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDtoList.add(videoInfoDto);
        });
        return Result.build(ResultState.OK, videoInfoDtoList);
    }

    @GetMapping("/search/{title}")
    public Result getVideoLikeTitle(@PathVariable("title") String title) {
        List<Video> videoByPage = videoService.getVideoLikeTitle(title);

        List<VideoInfoDto> videoInfoDtoList = new ArrayList<>();
        videoByPage.forEach(video -> {
            VideoInfoDto videoInfoDto = new VideoInfoDto();
            videoInfoDto.setId(video.getId());
            videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
            videoInfoDto.setLikeCount(video.getLikeCount());
            videoInfoDto.setVideoOriginName(video.getVideoOriginName());
            videoInfoDto.setTitle(video.getTitle());
            videoInfoDto.setM3u8Url(video.getM3u8Url());
            videoInfoDto.setType(video.getVideoType().getTypeName());
            videoInfoDto.setDescription(video.getDescription());
            videoInfoDto.setUserId(video.getUser().getId());
            videoInfoDto.setUsername(video.getUser().getUsername());
            videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
            videoInfoDto.setDuration(video.getVideoIndex().getDuration());
            videoInfoDtoList.add(videoInfoDto);
        });

        return Result.build(ResultState.OK, videoInfoDtoList);
    }

    @GetMapping("/info/{id}")
    public Result videoInfo(@PathVariable("id") Long id) {
        Video video = videoService.getVideoInfo(id);
        VideoInfoDto videoInfoDto = new VideoInfoDto();
        videoInfoDto.setId(video.getId());
        videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
        videoInfoDto.setLikeCount(video.getLikeCount());
        videoInfoDto.setVideoOriginName(video.getVideoOriginName());
        videoInfoDto.setTitle(video.getTitle());
        videoInfoDto.setM3u8Url(video.getM3u8Url());
        videoInfoDto.setType(video.getVideoType().getTypeName());
        videoInfoDto.setDescription(video.getDescription());
        videoInfoDto.setUserId(video.getUser().getId());
        videoInfoDto.setUsername(video.getUser().getUsername());
        videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
        videoInfoDto.setDuration(video.getVideoIndex().getDuration());
        return Result.build(ResultState.OK, videoInfoDto);
    }

    @SaCheckLogin
    @PostMapping("/add")
    public Result addVideo(@RequestBody AddVideoDto addVideoDto) {
        Long videoId = videoService.addVideo(addVideoDto.getTitle(),
                addVideoDto.getCoverImageUrl(),
                addVideoDto.getDescription(),
                addVideoDto.getM3u8Url(),
                addVideoDto.getType());

        if (videoId == -1L) {
            return Result.build(ResultState.INVALID_VIDEO_URL, null);
        } else if (videoId == -2L) {
            return Result.build(ResultState.NO_LOGIN, null);
        } else if (videoId == -3L) {
            return Result.build(ResultState.INVALID_VIDEO_TYPE, null);
        }

        Video video = videoService.getVideoInfo(videoId);
        VideoInfoDto videoInfoDto = new VideoInfoDto();
        videoInfoDto.setId(video.getId());
        videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
        videoInfoDto.setLikeCount(video.getLikeCount());
        videoInfoDto.setVideoOriginName(video.getVideoOriginName());
        videoInfoDto.setTitle(video.getTitle());
        videoInfoDto.setM3u8Url(video.getM3u8Url());
        videoInfoDto.setType(video.getVideoType().getTypeName());
        videoInfoDto.setDescription(video.getDescription());
        videoInfoDto.setUserId(video.getUser().getId());
        videoInfoDto.setUsername(video.getUser().getUsername());
        videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
        videoInfoDto.setDuration(video.getVideoIndex().getDuration());
        return Result.build(ResultState.OK, videoInfoDto);
    }

    @SaCheckLogin
    @DeleteMapping("/del/{videoId}")
    public Result delVideo(@PathVariable("videoId") Long videoId) {
        Long state = videoService.delVideo(videoId);
        if (state == -1L) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        } else if (state == -2L) {
            return Result.build(ResultState.VIDEO_USER_ID_NOTEQ_LOGIN_USER_ID, null);
        }

        return Result.build(ResultState.OK, state);
    }

    @SaCheckLogin
    @PostMapping("/like/{videoId}")
    public Result likeVideo(@PathVariable("videoId") Long videoId) {
        Long likeCount = videoService.likeVideo(videoId);
        if (likeCount == -1L) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        }

        return Result.build(ResultState.OK, likeCount);
    }

    @SaCheckLogin
    @GetMapping("/liked/{videoId}")
    public Result likedVideo(@PathVariable("videoId") Long videoId) {
        return Result.build(ResultState.OK,
                videoService.liked(videoId) ? 1 : 0);
    }

    @SaCheckLogin
    @PostMapping("/dislike/{videoId}")
    public Result dislikeVideo(@PathVariable("videoId") Long videoId) {
        Long likeCount = videoService.dislikeVideo(videoId);
        if (likeCount == -1L) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        }

        return Result.build(ResultState.OK, likeCount);
    }

    @SaCheckLogin
    @PostMapping("/collect/{videoId}")
    public Result collectVideo(@PathVariable("videoId") Long videoId) {
        Integer state = videoService.collectVideo(videoId);
        if (state == -1) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        }

        return Result.build(ResultState.OK, state);
    }

    @SaCheckLogin
    @GetMapping("/collected/{videoId}")
    public Result collectedVideo(@PathVariable("videoId") Long videoId) {
        return Result.build(ResultState.OK,
                videoService.collected(videoId) ? 1 : 0);
    }

    @SaCheckLogin
    @PostMapping("/uncollect/{videoId}")
    public Result uncollectVideo(@PathVariable("videoId") Long videoId) {
        Integer state = videoService.uncollectVideo(videoId);
        if (state == -1) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        }

        return Result.build(ResultState.OK, state);
    }

    @SaCheckLogin
    @PutMapping("/update/{videoId}")
    public Result updateVideo(@PathVariable("videoId") Long videoId,
                              @RequestBody UpdateVideoDto updateVideoDto) {
        int state = videoService.updateVideo(videoId,
                updateVideoDto.getTitle(),
                updateVideoDto.getDescription());

        if (state == -1) {
            return Result.build(ResultState.INVALID_VIDEO_ID, null);
        } else if (state == -2) {
            return Result.build(ResultState.VIDEO_USER_ID_NOTEQ_LOGIN_USER_ID, null);
        }

        Video video = videoService.getVideoInfo(videoId);
        VideoInfoDto videoInfoDto = new VideoInfoDto();
        videoInfoDto.setId(video.getId());
        videoInfoDto.setCoverImageUrl(video.getCoverImageUrl());
        videoInfoDto.setLikeCount(video.getLikeCount());
        videoInfoDto.setVideoOriginName(video.getVideoOriginName());
        videoInfoDto.setTitle(video.getTitle());
        videoInfoDto.setM3u8Url(video.getM3u8Url());
        videoInfoDto.setType(video.getVideoType().getTypeName());
        videoInfoDto.setDescription(video.getDescription());
        videoInfoDto.setUserId(video.getUser().getId());
        videoInfoDto.setUsername(video.getUser().getUsername());
        videoInfoDto.setUserAvatarUrl(video.getUser().getAvatarUrl());
        videoInfoDto.setDuration(video.getVideoIndex().getDuration());
        return Result.build(ResultState.OK, videoInfoDto);
    }
}
